package cn.jofei.core;

import cn.jofei.common.ano.Order;
import cn.jofei.common.ano.ServerLet;
import cn.jofei.common.config.AppProperties;
import cn.jofei.common.reflect.ReflectionMethod;
import cn.jofei.common.util.Utils;
import cn.jofei.core.container.Container;
import cn.jofei.core.starter.AppFunctionStarter;
import cn.jofei.netty.server.SocketServer;
import cn.jofei.server.http.filter.HttpRequestFilter;
import cn.jofei.server.http.filter.order.FilterOrder;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 端口监听 Starter
 *
 * @author Jofei Bao
 * @version ngbao v1.0.2
 * @date 2022/8/30 15:48
 */
public class NettyServerFunction implements AppFunctionStarter {

    private final String prefix = AppProperties.get("server.listen.prefix");

    // http 过滤器
    List<FilterOrder> filters = new ArrayList<>();

    //监听器列表
    private final List<String> listeners = new ArrayList<>();

    @Override
    public void beforeInject(Object o) {

    }

    @Override
    public void afterInject(Object o) {
        Class<?> aClass = o.getClass();

        if (o instanceof HttpRequestFilter) {
            Order order = o.getClass().getDeclaredAnnotation(Order.class);
            if (order != null) {
                log.info("添加请求过滤：{},顺序：{}", o.getClass(), order.index());
                filters.add(new FilterOrder(order.index(), (HttpRequestFilter) o));
            } else {
                throw new RuntimeException("Filter Order is required !");
            }
        }

        List<Class<?>> superClass = AppFunctionStarter.getSuperClass(aClass);
        if (superClass.size() > 0 && superClass.contains(SocketServer.class)) {
            listeners.add(Invoker.beanName(aClass));
        }
        // ServerLet 容器加载
        ServerLet annotation = aClass.getDeclaredAnnotation(ServerLet.class);
        if (annotation != null) {
            String path = annotation.path();
            if (!path.startsWith("/")) {
                path = "/" + path;
            }
            for (Method method : aClass.getDeclaredMethods()) {
                if (Utils.nonNull(method.getDeclaredAnnotations())) {
                    for (Annotation m : method.getDeclaredAnnotations()) {
                        if (m instanceof ServerLet) {
                            String methodPath = ((ServerLet) m).path();
                            if (!methodPath.startsWith("/")) {
                                methodPath = "/" + methodPath;
                            }
                            String serverLetPath = prefix + path + methodPath;
                            if (Container.SERVER_LET_MAP.containsKey(serverLetPath)) {
                                throw new RuntimeException("请求地址：" + serverLetPath + "已存在！");
                            } else {
                                log.info("加载serverLet路径：{}，方法：{}", serverLetPath, method);
                                Container.SERVER_LET_MAP.put(serverLetPath, new ReflectionMethod(Invoker.beanName(aClass), method));
                            }
                        }
                    }
                }
            }
        }
    }

    @Override
    public void start() {
        //添加请求过滤链
        HttpRequestFilter.FILTER_LIST.addAll(filters.stream()
                .sorted(Comparator.comparing(FilterOrder::getOrder))
                .map(FilterOrder::getFilter)
                .collect(Collectors.toList()));

        //启动端口监听
        for (String listener : listeners) {
            SocketServer var = (SocketServer) Container.BEAN_NAME_BEAN_MAPPING.get(listener);
            var.start();
        }
        listeners.clear();
    }
}
